package com.levi.juc.coll_unsafe.list_set;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;

/**
 * 1.CopyOnWriteArrayList是线程安全的,    写入的时候复制一份，跟ThreadLocal原理相似
 * 2.HashSet是不安全的，多线程情况下会出现ConcurrentModificationException异常，解决方案用CopyOnWriteArraySet
 *
 * 原理:   CopyOnWriteArrayList的实现原理是，在一个线程开始遍历（创建Iterator对象）时，内部会创建一个“快照”数组，
 * 遍历基于这个快照Iterator进行，在遍历过程中这个快照数组不会改变，也就不会抛出ConcurrentModificationException。
 * 如果在遍历的过程中有其他线程尝试改变数组的内容，就会拷贝一份新的数据进行变更，而后面再来访问这个数组的线程，看到的就是变更过的数组
 */
public class CopyOnWriteTest {
    public static void main(String[] args) {
//        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
//        long start = System.currentTimeMillis();
//        for (int i = 0; i < 10; i++) {
//            new Thread(()->{
//                list.add(UUID.randomUUID().toString().substring(0, 5));
//                System.out.println(list);
//            }).start();
//        }
//        long end = System.currentTimeMillis();
//        long use = end - start;
//        System.out.println(use);

        HashSet<String> strings = new HashSet<>();
        Map<String,String> map = new HashMap<>();
        Set<String> set = new CopyOnWriteArraySet<>();
        for (int i = 0; i < 20; i++) {
            new Thread(()->{
                set.add(UUID.randomUUID().toString().substring(0, 5));
                System.out.println(set);
            }).start();
        }


        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();
        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                list.add(UUID.randomUUID().toString().substring(0, 5));
                System.out.println(list);
            }, UUID.randomUUID().toString().substring(0, 2)).start();
        }
    }
}
